package views;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

import objects.FeatureList;
import objects.Lexicon;
import objects.LexiconList;
import objects.Stem;

public class ViewLexicon extends JFrame {
	
	/* Data variables */
	private String buttonSelected;
	private Lexicon lexicon;
	
	/** Component variables **/
	
	private JTable table;
	private DefaultTableModel tableModel;
	
	private JComboBox<String> cmbSyntacticCategory;
	private JComboBox<String> cmbConcept;
	private JComboBox<String> cmbSense;
	
	private JButton btnLoadLexiconFile;
	private JButton btnSaveLexiconFile;
	
	private JButton btnGo;
	private JButton btnAddSyntacticCategory;
	
	private JButton btnAddLexicon;
	private JButton btnAddFeature;
	private JButton btnAddForm;
	
	private JButton btnStems;
	private JButton btnFeatures;
	private JButton btnForms;
	
	public ViewLexicon() {
		buttonSelected = "Stems";
		
		tableModel = new DefaultTableModel(new Object[][] {{null, null}}, new String[] {"Stem", "Concept", "Sense"});
		 
		cmbSense = new JComboBox<String>();
		cmbConcept = new JComboBox<String>();
		
		setTitle("Lexicon");
		setMinimumSize(new Dimension(650, 500));
		setSize(new Dimension(650, 500));
		setLocationRelativeTo(null);
		getContentPane().setLayout(null);getContentPane().setLayout(new BorderLayout(0, 0));
		
		JPanel panContentRight = new JPanel();
		getContentPane().add(panContentRight, BorderLayout.EAST);
		
		JPanel panContentLeft = new JPanel();
		getContentPane().add(panContentLeft, BorderLayout.WEST);
		
		JPanel panTop = new JPanel();
		getContentPane().add(panTop, BorderLayout.NORTH);
		panTop.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopTop = new JPanel();
		panTop.add(panTopTop, BorderLayout.NORTH);
		
		JPanel panTopCenter = new JPanel();
		panTop.add(panTopCenter, BorderLayout.CENTER);
		panTopCenter.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopTopRight = new JPanel();
		panTopCenter.add(panTopTopRight, BorderLayout.EAST);
		panTopTopRight.setLayout(new BorderLayout(0, 0));
		
		JPanel panViews = new JPanel();
		panTopTopRight.add(panViews);
		panViews.setBorder(new TitledBorder(null, "Views", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panViews.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 2));
		
		btnStems = new JButton("Stems");
		panViews.add(btnStems);
		
		btnFeatures = new JButton("Features");
		panViews.add(btnFeatures);
		
		btnForms = new JButton("Forms");
		panViews.add(btnForms);
		
		JPanel panTopTopRightRight = new JPanel();
		panTopTopRight.add(panTopTopRightRight, BorderLayout.EAST);
		
		JPanel panTopTopLeft = new JPanel();
		panTopCenter.add(panTopTopLeft, BorderLayout.WEST);
		panTopTopLeft.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopLeftSpace = new JPanel();
		panTopTopLeft.add(panTopLeftSpace, BorderLayout.WEST);
		
		JPanel panTopTopLeftCenter = new JPanel();
		panTopTopLeft.add(panTopTopLeftCenter, BorderLayout.CENTER);
		panTopTopLeftCenter.setLayout(new BorderLayout(0, 0));
		
		JPanel panChooseCategory = new JPanel();
		FlowLayout flowLayout_2 = (FlowLayout) panChooseCategory.getLayout();
		flowLayout_2.setHgap(1);
		flowLayout_2.setAlignment(FlowLayout.LEFT);
		flowLayout_2.setVgap(3);
		panTopTopLeftCenter.add(panChooseCategory, BorderLayout.NORTH);
		
		JLabel lblSyntacticCategory = new JLabel("Syntactic Category:");
		panChooseCategory.add(lblSyntacticCategory);
		
		JPanel panel = new JPanel();
		panChooseCategory.add(panel);
		
		cmbSyntacticCategory = new JComboBox<String>();
		panChooseCategory.add(cmbSyntacticCategory);
		
		btnAddSyntacticCategory = new JButton("Add Syntactic Category");
		panTopTopLeftCenter.add(btnAddSyntacticCategory, BorderLayout.CENTER);
		
		JPanel panTopTopLeftRight = new JPanel();
		panTopTopLeft.add(panTopTopLeftRight, BorderLayout.EAST);
		panTopTopLeftRight.setLayout(new BorderLayout(0, 0));
		
		JPanel panGo = new JPanel();
		FlowLayout fl_panGo = (FlowLayout) panGo.getLayout();
		fl_panGo.setVgap(1);
		panTopTopLeftRight.add(panGo, BorderLayout.NORTH);
		
		btnGo = new JButton("Go");
		panGo.add(btnGo);
		
		JPanel panTopBottom = new JPanel();
		panTop.add(panTopBottom, BorderLayout.SOUTH);
		panTopBottom.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopBottomRight = new JPanel();
		panTopBottom.add(panTopBottomRight, BorderLayout.EAST);
		panTopBottomRight.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopBottomRightCenter = new JPanel();
		panTopBottomRight.add(panTopBottomRightCenter, BorderLayout.CENTER);
		panTopBottomRightCenter.setLayout(new BorderLayout(0, 0));
		
		JPanel panLoad = new JPanel();
		panTopBottomRightCenter.add(panLoad, BorderLayout.NORTH);
		FlowLayout flowLayout_4 = (FlowLayout) panLoad.getLayout();
		flowLayout_4.setHgap(0);
		flowLayout_4.setVgap(2);
		
		btnLoadLexiconFile = new JButton("Load Lexicon File");
		panLoad.add(btnLoadLexiconFile);
		
		JPanel panSave = new JPanel();
		panTopBottomRightCenter.add(panSave, BorderLayout.SOUTH);
		FlowLayout flowLayout_5 = (FlowLayout) panSave.getLayout();
		flowLayout_5.setHgap(0);
		flowLayout_5.setVgap(2);
		
		btnSaveLexiconFile = new JButton("Save Lexicon File");
		panSave.add(btnSaveLexiconFile);
		
		JPanel panTopBottomRightRight = new JPanel();
		panTopBottomRight.add(panTopBottomRightRight, BorderLayout.EAST);
		
		JPanel panTopBottomLeft = new JPanel();
		panTopBottom.add(panTopBottomLeft, BorderLayout.WEST);
		panTopBottomLeft.setLayout(new BorderLayout(0, 0));
		
		JPanel panTopBottomInner = new JPanel();
		panTopBottomLeft.add(panTopBottomInner, BorderLayout.SOUTH);
		panTopBottomInner.setLayout(new BorderLayout(0, 0));
		
		JPanel panSpaceLeft = new JPanel();
		panTopBottomInner.add(panSpaceLeft, BorderLayout.WEST);
		
		JPanel panAdd = new JPanel();
		panTopBottomInner.add(panAdd, BorderLayout.CENTER);
		FlowLayout flowLayout_1 = (FlowLayout) panAdd.getLayout();
		flowLayout_1.setHgap(0);
		flowLayout_1.setVgap(2);
		flowLayout_1.setAlignment(FlowLayout.LEFT);
		
		btnAddLexicon = new JButton("Add Lexicon");
		panAdd.add(btnAddLexicon);
		
		JPanel panAddFeature = new JPanel();
		FlowLayout fl_panAddFeature = (FlowLayout) panAddFeature.getLayout();
		fl_panAddFeature.setVgap(0);
		panAdd.add(panAddFeature);
		
		btnAddFeature = new JButton("Add Feature");
		panAddFeature.add(btnAddFeature);
		
		btnAddForm = new JButton("Add Form");
		panAdd.add(btnAddForm);
		
		JPanel panContent = new JPanel();
		getContentPane().add(panContent, BorderLayout.CENTER);
		panContent.setLayout(new BorderLayout(0, 0));
		
		JPanel panContentBottom = new JPanel();
		panContent.add(panContentBottom, BorderLayout.SOUTH);
		
		JPanel panContentTop = new JPanel();
		panContent.add(panContentTop, BorderLayout.NORTH);
		
		JScrollPane scrollPane = new JScrollPane();
		panContent.add(scrollPane, BorderLayout.CENTER);
		
		table = new JTable(tableModel) {
			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
		};
		scrollPane.setViewportView(table);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		
		TableColumnAdjuster adjuster = new TableColumnAdjuster(table);
		adjuster.setDynamicAdjustment(true);
		adjuster.adjustColumns();
		
		refreshCmbSyntacticCategory();
		refreshTable();
	}
	
	/** Table methods **/
	
	public void refreshTable() {
		if (lexicon != null) {
			if (lexicon.getLexiconList() != null) {
				String selectedLabel = cmbSyntacticCategory.getSelectedItem().toString().toLowerCase();
				
				for (LexiconList lexiconList : lexicon.getLexiconList()) {
					String label = lexiconList.getLabel().toLowerCase();
					
					if (selectedLabel != null && selectedLabel.equals(label)) {
						if (buttonSelected.equalsIgnoreCase("forms")) {
							setColumnForm(lexiconList.getFormList());
						}
						else if (buttonSelected.equalsIgnoreCase("features")) {
							setColumnFeature(lexiconList.getFeatureList());
						}
						else if (buttonSelected.equalsIgnoreCase("stems")) {
							setColumnStem(lexiconList);
						}
						setRow(lexiconList.getStemList());
						break;
					}
				}
			}
		}
	}
	
	public void setColumnForm(ArrayList<String> forms) {
		tableModel = new DefaultTableModel();
		tableModel.addColumn("Stem");
		for (int i = 0; i < forms.size(); i++) {
			tableModel.addColumn(forms.get(i));
		}
		table.setModel(tableModel);
		table.revalidate();
		table.repaint();
	}
	
	public void setColumnFeature(ArrayList<FeatureList> arrayList) {
		tableModel = new DefaultTableModel();
		tableModel.addColumn("Stem");
		for (int i = 0; i < arrayList.size(); i++) {
			tableModel.addColumn(arrayList.get(i).getName());
		}
		table.setModel(tableModel);
		table.revalidate();
		table.repaint();
	}
	
	public void setColumnStem(LexiconList lexiconList) {
		tableModel = new DefaultTableModel();
		tableModel.addColumn("Stem");
		tableModel.addColumn("Concept");
		tableModel.addColumn("Sense");
		table.setModel(tableModel);
		table.revalidate();
		table.repaint();
	}
	
	public void setRow(ArrayList<Stem> stemList) {
		for (int i = 0; i < tableModel.getRowCount(); i++) {
			tableModel.removeRow(i);
		}
		
		if (stemList != null) {
			for (int j = 0; j < stemList.size(); j++) {
				ArrayList<String> data = new ArrayList<String>();
				data.add(stemList.get(j).getValue().toString());
				
				if (buttonSelected.equalsIgnoreCase("stems")) {
					data.add(stemList.get(j).getConcept());
					data.add(stemList.get(j).getSense());
				}
				
				if (buttonSelected.equalsIgnoreCase("forms")) {
					for (int k = 0; k < stemList.get(j).getFormList().size(); k++) {
						data.add(stemList.get(j).getFormList().get(k).getValue());
					}
				}
				
				else if (buttonSelected.equalsIgnoreCase("features")) {
					for (int l = 0; l < stemList.get(j).getFeatureList().size(); l++) {
						data.add(stemList.get(j).getFeatureList().get(l).getValue());
					}
				}
				tableModel.insertRow(j, data.toArray());
			}
		}
		table.revalidate();
		table.repaint();
	}
	
	public void addRow(String[] value) {
		tableModel.addRow(value);
	}
	
	public void clearTable() {
		while (tableModel.getRowCount() > 0) {
			tableModel.removeRow(0);
		}
	}
	
	public int getSelectedRow() {
		return table.getSelectedRow();
	}
	
	public int getSelectedColumn() {
		return table.getSelectedColumn();
	}
	
	public int findColumn(String column) {
		return tableModel.findColumn(column);
	}
	
	public String getColumnName(int index) {
		return table.getColumnName(index);
	}
	
	/** ComboBox methods **/
	
	public void refreshCmbSyntacticCategory() {
		cmbSyntacticCategory.removeAllItems();
		
		if (lexicon != null) {
			if (lexicon.getLexiconList() != null) {
				for (int i = 0; i < lexicon.getLexiconList().size(); i++) {
					if (lexicon.getLexiconList().get(i).getLabel() != null) {
						cmbSyntacticCategory.addItem(lexicon.getLexiconList().get(i).getLabel());
					}
				}
				
				cmbSyntacticCategory.repaint();
				cmbSyntacticCategory.revalidate();
			}
		}
	}
	
	public void addCategoryToChooser(String syntacticCategory) {
		cmbSyntacticCategory.addItem(syntacticCategory);
	}
	
	public void removeAllCategories() {
		cmbSyntacticCategory.removeAllItems();
	}
	
	public String getSelectedCategory() {
		return cmbSyntacticCategory.getSelectedItem().toString();
	}
	
	public void addConceptToChooser(String concept) {
		cmbConcept.addItem(concept);
	}
	
	public void removeAllConcepts() {
		cmbConcept.removeAllItems();
	}
	
	public void setSelectedConcept(String select) {
		cmbConcept.setSelectedItem(select);
	}
	
	public String getSelectedConcept() {
		return (String) cmbConcept.getSelectedItem();
	}
	
	public void addSenseToChooser(String sense) {
		cmbSense.addItem(sense);
	}
	
	public void removeAllSenses() {
		cmbSense.removeAllItems();
	}
	
	public String getSelectedSense() {
		return (String) cmbSense.getSelectedItem();
	}
	
	/** Get or set data **/
	
	public void setButtonSelected(String buttonSelected) {
		this.buttonSelected = buttonSelected;
	}
	
	public String getButtonSelected() {
		return buttonSelected;
	}
	
	public void setLexicon(Lexicon lexicon) {
		this.lexicon = lexicon;
		
		refreshCmbSyntacticCategory();
		refreshTable();
	}
	
	/** Get or set components **/
	
	public DefaultTableModel getTableModel() {
		return tableModel;
	}
	
	public JComboBox<String> getCmbConcept() {
		return cmbConcept;
	}
	
	public JComboBox<String> getCmbSense() {
		return cmbSense;
	}
	
	/** Add listeners **/
	
	public void addViewsButtonsListener(ActionListener listener) {
		btnStems.addActionListener(listener);
		btnFeatures.addActionListener(listener);
		btnForms.addActionListener(listener);
	}
	
	public void addLoadLexiconActionListener(ActionListener listener) {
		btnLoadLexiconFile.addActionListener(listener);
	}
	
	public void addSaveLexiconActionListener(ActionListener listener) {
		btnSaveLexiconFile.addActionListener(listener);
	}
	
	public void addLoadSyntacticCategoryListener(ActionListener listener) {
		btnGo.addActionListener(listener);
	}
	
	public void addSyntacticListener(ActionListener listener) {
		btnAddSyntacticCategory.addActionListener(listener);
	}
	
	public void addLexiconListener(ActionListener listener) {
		btnAddLexicon.addActionListener(listener);
	}
	
	public void addFeatureListener(ActionListener listener) {
		btnAddFeature.addActionListener(listener);
	}
	
	public void addFormListener(ActionListener listener) {
		btnAddForm.addActionListener(listener);
	}
	
	public void addTableListener(MouseListener listener) {
		table.addMouseListener(listener);
	}
	
	public void addLoadConceptSenseListener(ItemListener listener) {
		cmbConcept.addItemListener(listener);
	}
}
